#include "umQueue.h"



void  QueInit(S_QUEUE *que)
{    
#if USEMUTEXT
	umapi_os_mutex_create(UM_NULL, UM_OS_MUTEX_ATTR_RECURSIVE_NP, &que->mutexHandle);
	umapi_list_create(&que->head);
#else
	S_QUEUE_NODE *temp = (S_QUEUE_NODE*)malloc(sizeof(S_QUEUE_NODE)); 
	memset(temp, 0, sizeof(S_QUEUE_NODE));
	assert(temp!=NULL);    
	temp->next=NULL;	
	que->front = que->rear = temp;
#endif
}
int QueEmpty(S_QUEUE *que)
{   
#if USEMUTEXT
	return umapi_list_empty(&que->head);
#else
	return __sync_bool_compare_and_swap(&(que->rear), que->front, que->front);
#endif
}
void QuePush(S_QUEUE *que, UM_VOID *d)
{ 
#if USEMUTEXT
	S_QUEUE_NODE *node = (S_QUEUE_NODE*)umapi_malloc(sizeof(S_QUEUE_NODE));
	node->data = d;
	while(umapi_os_mutex_lock(que->mutexHandle, 1) != UM_SUCCESS)
	{
		;
	}	
	umapi_list_add(&node->head, &que->head);
	umapi_os_mutex_unlock(que->mutexHandle);
#else
	S_QUEUE_NODE *temp = (S_QUEUE_NODE*)malloc(sizeof(S_QUEUE_NODE));   
	memset(temp, 0, sizeof(S_QUEUE_NODE));
	assert(temp!=NULL);   
	temp->data = d;    
	S_QUEUE_NODE* p;    
	do    
	{        
		p = que->rear; 
		printf("p->next:%p\n", p->next);
	} while(!__sync_bool_compare_and_swap(&(p->next),NULL,temp));    
	__sync_bool_compare_and_swap(&(que->rear), p, temp);
#endif	
}
int QuePop(S_QUEUE *que,  UM_VOID **d)
{  
#if USEMUTEXT
	if(umapi_list_empty(&que->head))
		return 0;
	while(umapi_os_mutex_lock(que->mutexHandle, 1) != UM_SUCCESS)
	{
		;
	}	
	int ret = 0;
	struct umapi_list_head *pos,*n;
	umapi_list_for_each_safe(pos, n, &que->head)
	{
		S_QUEUE_NODE *node = umapi_list_entry(pos, S_QUEUE_NODE, head);
		umapi_list_del(&node->head);
		*d = node->data;
		umapi_free(node);
		ret = 1;
		break;
	}
	umapi_os_mutex_unlock(que->mutexHandle);
	return ret;
#else
	S_QUEUE_NODE *temp;    
	S_QUEUE_NODE *p;     
	do    
	{       
		if(QueEmpty(que))            
			return 0;        
		temp = que->front->next;        
		if(temp!=NULL)            
			p=temp->next;        
		else            
			p=NULL;    
	}while(!__sync_bool_compare_and_swap(&(que->front->next), temp, p));    
	__sync_bool_compare_and_swap(&(que->rear), temp, que->front);    
	if(temp!=NULL)    
	{        
		*d = temp->data;        
		free(temp);        
		return 1;    
	}    
	return 0;
#endif	
}



